/* 
   Copyright(C)2012 Fredy Ramirez - www.pacificcoolwave.com
 
   This file is part of the TerraCool project.
	
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

using System;
using System.Collections.Generic;
using Pcw.TerraCool.Tools;

namespace Pcw.TerraCool.Util
{
	internal enum OperationType 
	{
		CreateLocale,
		UpdateLocale,
		MergeLocale,
		None
	}

	internal static class MainClass
	{
		[STAThread]
		public static int Main (string[] args)
		{
			TerraCool.Init("TerraCoolUtil", Environment.CurrentDirectory);

			Show.Head();

			Dictionary <string, string> arguments = GetArgumentsDictionary(args);
			if (arguments == null || arguments.Count == 0){
				Show.License();
				return ReturnWithMessage(0, String.Empty);
			}

			OperationType type = OperationType.None; 
			SourceType sourceType = SourceType.NotDefined;
			string outPut = null;
			bool overwrite = true;
			string directory = null;
			string[] source = null;
			char[] listBreakChar = new char[] {','};

			foreach(KeyValuePair<string, string> pair in arguments) 
			{
				switch(pair.Key.ToLower()) 
				{
					case "-c":
					case "--create":
						type = OperationType.CreateLocale;
						break;
					case "-u":
					case "--update":
						type = OperationType.UpdateLocale;
						break;
					case "-m":
					case "--merge":
						type = OperationType.MergeLocale;
						break;
					case "-o":
					case "--output":
						outPut = pair.Value;
						break;
					case "--overwrite-false":
						overwrite = false;
						break;
					case "-d":
					case "--directory":
						directory = pair.Value;
						break;
					case "-s":
					case "--source":
						if (pair.Value != null)
							source = pair.Value.Split(listBreakChar);
						break;
					case "--type-csharp":
						if (sourceType != SourceType.NotDefined)
							return ReturnWithMessage(1, TerraCool.GetString("Source type must be set only to one type."));
						sourceType = SourceType.csharp;
						break;
					case "--type-vb":
						return ReturnWithMessage(2, TerraCool.GetString("Source type 'vb' is not supported at this moment"));
					case "-l":
					case "--license":
						Show.License();
						return ReturnWithMessage(0, String.Empty);
					case "--help":
					case "-h":
					case "-?":
						Show.Help();
						return ReturnWithMessage(0, String.Empty);
					default:
						Console.WriteLine(TerraCool.GetString("Unknown parameter '{0}'"), pair.Key);
						Console.WriteLine();
						Show.Help();
						return ReturnWithMessage(3, String.Empty);
				}
			}

			if (type == OperationType.None)
				return ReturnWithMessage(4, TerraCool.GetString("Parameter -c, -u or -m must be set."));

			if (outPut == null) 
				return ReturnWithMessage(5 ,TerraCool.GetString("Parameter --output must be set."));

			if (source == null) 
				return ReturnWithMessage(6, TerraCool.GetString("Parameter --source must be set."));

			if (directory == null)
				directory = Environment.CurrentDirectory;

			string fileOutput = LocaleFile.GetFileFullPath(outPut, "xml", Environment.CurrentDirectory, false);

			List<string> src = new List<string>();
			string f = null;
			foreach(string s in source) {
				f = LocaleFile.GetFileFullPath(s, null, directory, true);
				if (String.IsNullOrEmpty(f)) {
					Console.WriteLine(TerraCool.GetString("Source file '{0}' not found. Ignored."), s);
					continue;
				}
				src.Add(f);
			}

			if (src.Count == 0) 
				return ReturnWithMessage(7, TerraCool.GetString("No sources found."));

			if (sourceType == SourceType.NotDefined)
				sourceType = SourceType.csharp; // Use this as default

			if (type == OperationType.CreateLocale) 
				LocaleFile.CreateLocaleFile(sourceType, fileOutput, src, overwrite);

			Console.WriteLine(TerraCool.GetPluralString ("Operation finished. {0} source file processed.", 
			                                           "Operation finished. {0} source files processed.", src.Count), src.Count);
			Console.WriteLine();
			return 0;
		}

		private static Dictionary<string,string> GetArgumentsDictionary(string[] args)
		{
			Dictionary<string,string> result = new Dictionary<string, string>();

			string key = null;
			string val = null;

			try 
			{
				for(int i = 0; i < args.Length; i++) 
				{
					val = null;
					if (args[i].StartsWith("-")){
						key = args[i];
						if (i < args.Length - 1 && !args[i+1].StartsWith("-")){
							val = args[i+1];
							i++;
						}
						result.Add(key,val);
						continue;
					}
					else {
						Console.WriteLine(TerraCool.GetString("ERROR: Invalid argument format near '{0}'. Run --help for more information."), args[i]);
						return null;
					}
				}
			}
			catch (Exception e)
			{
				Console.WriteLine(TerraCool.GetString("Error while trying to get arguments dictionary.") + " - " + e.Message );
				return null;
			}

			return result;
		}

		private static int ReturnWithMessage(int code, string message) 
		{
			Console.WriteLine(message);
			return code;
		}
	}
}
